//
//  KSHObjcUML.m
//  KSHObjcUML
//
//  Created by 金聖輝 on 15-2-18.
//  Copyright (c) 2015年 KimSungwhee. All rights reserved.
//

#import "KSHObjcUML.h"

#import "VWKShellHandler.h"
#import "VWKWorkspaceManager.h"
#import "VWKProject.h"

static KSHObjcUML *sharedPlugin;

static NSString *BIN_PATH            = @"/bin";
static NSString *USER_BIN_PATH       = @"/usr/bin";
static NSString *USER_LOCAL_BIN_PATH = @"/usr/local/bin";

static NSString *COPY_EXECUTABLE        = @"cp";
static NSString *RM_EXECUTABLE          = @"rm";
static NSString *UNZIP_EXECUTABLE       = @"unzip";
static NSString *OPEN_EXECUTABLE        = @"open";
static NSString *ZIP_FILE_NAME          = @"ObjcUML.zip";
static NSString *FOLDAR_NAME            = @"ObjcUML";
static NSString *RUBY_EXECUTE_FILE_NAME = @"script.rb";
static NSString *HTML_FILE              = @"index.html";
static NSString *OUT_PUT_JS_FILE        = @"origin.js";

@interface KSHObjcUML ()

@property (nonatomic, strong, readwrite) NSBundle *bundle;
@property (nonatomic, copy) NSString              *directoryPath;
@property (nonatomic, copy) NSString              *zipFilePath;
@property (nonatomic, copy) NSString              *projectName;
@property (nonatomic, copy) NSString              *scriptPath;

@end

@implementation KSHObjcUML

+ (NSBundle *)pluginBundle
{
    return [NSBundle bundleForClass:self];
}

- (NSString *)scriptPath
{
    NSString *tempScriptPath = [self.foldarName stringByAppendingPathComponent:@"script.rb"];
    if (tempScriptPath) {
        _scriptPath = tempScriptPath;
    }
    return _scriptPath;
}

- (NSString *)projectName
{
    NSString *tempProjectName = self.project.projectOriginalName;
    if (tempProjectName) {
        // When the project name contains “ ” replace to "_"
        _projectName = [tempProjectName stringByReplacingOccurrencesOfString:@" " withString:@"_"];
    }
    return _projectName;
}

- (NSString *)zipFilePath
{
    NSString *tempZipFilePath = [[KSHObjcUML pluginBundle] pathForResource:FOLDAR_NAME ofType:@"zip"];
    if (tempZipFilePath) {
        _zipFilePath = tempZipFilePath;
    }
    return _zipFilePath;
}

- (NSString *)directoryPath
{
    NSString *tempDirectoryPath = self.project.directoryPath;
    if (tempDirectoryPath) {
        _directoryPath = tempDirectoryPath;
    }
    return _directoryPath;
}

+ (void)pluginDidLoad:(NSBundle *)plugin
{
    static dispatch_once_t onceToken;
    NSString *currentApplicationName = [[NSBundle mainBundle] infoDictionary][@"CFBundleName"];
    if( [currentApplicationName isEqual:@"Xcode"] )
    {
        dispatch_once(&onceToken, ^{
            sharedPlugin = [[self alloc] initWithBundle:plugin];
        });
    }
}

+ (instancetype)sharedPlugin
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedPlugin = [[self alloc] initWithBundle:nil];
    });
    return sharedPlugin;
}

- (id)initWithBundle:(NSBundle *)plugin
{
    if( self = [super init] )
    {
        self.bundle = plugin;
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            NSMenuItem *menuItem = [[NSApp mainMenu] itemWithTitle:@"Product"];
            if( menuItem )
            {
                [[menuItem submenu] addItem:[NSMenuItem separatorItem]];
                NSMenuItem *objcActionMenuItem = [[NSMenuItem alloc] initWithTitle:@"Objc-UML" action:@selector(startGenerateObjcGraph) keyEquivalent:@""];
                [objcActionMenuItem setTarget:self];
                [[menuItem submenu] insertItem:objcActionMenuItem atIndex:[menuItem.submenu indexOfItemWithTitle:@"Build For"]];
                NSMenuItem *swiftActionMenuItem = [[NSMenuItem alloc] initWithTitle:@"Swift-UML" action:@selector(startGenerateSwiftGraph) keyEquivalent:@""];
                [swiftActionMenuItem setTarget:self];
                [[menuItem submenu] insertItem:swiftActionMenuItem atIndex:[menuItem.submenu indexOfItemWithTitle:@"Build For"]];
            }
        }];
    }
    
    return self;
}

- (NSString*)foldarName
{
    NSString *foldarName = [self.directoryPath stringByAppendingPathComponent:FOLDAR_NAME];
    return foldarName;
}

- (NSString*)rmCommand
{
    NSString *rm = [BIN_PATH stringByAppendingPathComponent:RM_EXECUTABLE];
    return rm;
}

-(NSString*)copyZipFile
{
    return [self.directoryPath stringByAppendingPathComponent:ZIP_FILE_NAME];
}

- (void)startGenerateObjcGraph
{
    [self startGenerateGraph:@"-d"];
}

- (void)startGenerateSwiftGraph
{
    [self startGenerateGraph:@"-w"];
}

- (void)startGenerateGraph:(NSString*)generateType
{
    // copy: ObjcUML.zip ,保证原文件不破坏
    [VWKShellHandler runShellCommand:[BIN_PATH stringByAppendingPathComponent:COPY_EXECUTABLE]
                            withArgs:@[self.zipFilePath, self.directoryPath]
                           directory:self.directoryPath
                          completion:^(NSTask *t, NSString *standardOutputString, NSString *standardErrorString)
    {
        // unzip: 解压缩ObjcUML.zip
        [VWKShellHandler runShellCommand:[USER_BIN_PATH stringByAppendingPathComponent:UNZIP_EXECUTABLE]
                                withArgs: @[@"-o", @"-d", self.directoryPath, self.copyZipFile]
                               directory:self.directoryPath
                              completion:^(NSTask* t, NSString* standardOutputString, NSString* standardErrorString)
        {
            // rm: 删除copy的zip文件
            [VWKShellHandler runShellCommand:self.rmCommand
                                    withArgs:@[@"-rf", self.copyZipFile]
                                   directory:self.directoryPath
                                  completion:^(NSTask *t, NSString *standardOutputString, NSString *standardErrorString)
            {
                // ***script.rb
                // -d Objc
                // -w Swift
                [VWKShellHandler runShellCommand:self.scriptPath
                                        withArgs:@[@"-f",@"json-var",generateType,@"-s",[NSString stringWithFormat:@"\"%@\"",self.projectName], @"-t", [self.foldarName stringByAppendingPathComponent:OUT_PUT_JS_FILE]]
                                       directory:self.directoryPath
                                      completion:^(NSTask *t, NSString *standardOutputString, NSString *standardErrorString)
                {
                    // open:
                    [VWKShellHandler runShellCommand:[USER_BIN_PATH stringByAppendingPathComponent:OPEN_EXECUTABLE]
                                            withArgs:@[[self.foldarName stringByAppendingPathComponent:HTML_FILE]]
                                           directory:self.directoryPath
                                          completion:nil];
                    // 删除rb文件
//                    // rm:script.rb
//                    [VWKShellHandler runShellCommand:self.rmCommand
//                                            withArgs:@[@"-rf", [self.foldarName stringByAppendingPathComponent:@"script.rb"]]
//                                           directory:self.directoryPath
//                                          completion:^(NSTask *t, NSString *standardOutputString,NSString *standardErrorString)
//                    {
//                        // rm:objc_dependencies_generator.rb
//                        [VWKShellHandler runShellCommand:self.rmCommand
//                                                withArgs:@[@"-rf", [self.foldarName stringByAppendingPathComponent:@"objc_dependencies_generator.rb"]]
//                                               directory:self.directoryPath
//                                              completion:^(NSTask *t, NSString *standardOutputString,NSString *standardErrorString)
//                        {
//                            // rm:objc_dependency_tree_generator_helper.rb
//                            [VWKShellHandler runShellCommand:self.rmCommand
//                                                    withArgs:@[@"-rf", [self.foldarName stringByAppendingPathComponent:@"objc_dependency_tree_generator_helper.rb"]]
//                                                   directory:self.directoryPath
//                                                  completion:^(NSTask *t, NSString *standardOutputString,NSString *standardErrorString)
//                            {
//                                // rm:objc_dependency_tree_generator.rb
//                                [VWKShellHandler runShellCommand:self.rmCommand
//                                                        withArgs:@[@"-rf", [self.foldarName stringByAppendingPathComponent:@"objc_dependency_tree_generator.rb"]]
//                                                       directory:self.directoryPath
//                                                      completion:^(NSTask *t, NSString *standardOutputString,NSString *standardErrorString)
//                                {
//                                    // rm:swift_dependencies_generator.rb
//                                    [VWKShellHandler runShellCommand:self.rmCommand
//                                                            withArgs:@[@"-rf", [self.foldarName stringByAppendingPathComponent:@"swift_dependencies_generator.rb"]]
//                                                           directory:self.directoryPath
//                                                          completion:^(NSTask *t, NSString *standardOutputString,NSString *standardErrorString)
//                                    {
//                                        // open:
//                                        [VWKShellHandler runShellCommand:[USER_BIN_PATH stringByAppendingPathComponent:OPEN_EXECUTABLE]
//                                                                withArgs:@[[self.foldarName stringByAppendingPathComponent:HTML_FILE]]
//                                                               directory:self.directoryPath
//                                                              completion:nil];
//                                    }];
//                                }];
//                            }];
//                        }];
//                    }];
                }];
            }];
        }];
    }];
}

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

@end
